// Package model provides secure user data models
package model

import (
	"fmt"
	"time"

	"gorm.io/gorm"
)

// UserModel represents user data with security enhancements
type UserModel struct {
	Id        int64     `gorm:"column:id;primaryKey" json:"id"`
	UserName  string    `gorm:"column:username;uniqueIndex;not null" json:"username"`
	Email     string    `gorm:"column:email;uniqueIndex;not null" json:"email"`
	FirstName string    `gorm:"column:first_name" json:"first_name"`
	LastName  string    `gorm:"column:last_name" json:"last_name"`
	
	// Security fields - never expose in JSON
	PasswordHash string `gorm:"column:password_hash;not null" json:"-"`
	Salt         string `gorm:"column:salt;not null" json:"-"`
	Role         string `gorm:"column:role;default:'user'" json:"role"`
	IsActive     bool   `gorm:"column:is_active;default:true" json:"is_active"`
	
	// Profile fields
	Avatar    string    `gorm:"column:avatar" json:"avatar"`
	LastLogin time.Time `gorm:"column:last_login" json:"last_login"`
	
	// Security and audit fields
	FailedLoginAttempts int       `gorm:"column:failed_login_attempts;default:0" json:"-"`
	LockedUntil         time.Time `gorm:"column:locked_until" json:"-"`
	PasswordChangedAt   time.Time `gorm:"column:password_changed_at" json:"-"`
	EmailVerified       bool      `gorm:"column:email_verified;default:false" json:"email_verified"`
	EmailVerifiedAt     time.Time `gorm:"column:email_verified_at" json:"-"`
	
	// Timestamps
	CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
	UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
}

func (user *UserModel) TableName() string {
	return "users"
}

// BeforeUpdate hook for automatic timestamp update
func (u *UserModel) BeforeUpdate(*gorm.DB) error {
	u.UpdatedAt = time.Now()
	fmt.Printf("[%s] User update triggered for ID: %d\n", u.UpdatedAt.String(), u.Id)
	return nil
}

// IsLocked checks if the user account is locked
func (u *UserModel) IsLocked() bool {
	return u.LockedUntil.After(time.Now())
}

// Lock locks the user account for the specified duration
func (u *UserModel) Lock(duration time.Duration) {
	u.LockedUntil = time.Now().Add(duration)
}

// Unlock unlocks the user account
func (u *UserModel) Unlock() {
	u.LockedUntil = time.Time{}
	u.FailedLoginAttempts = 0
}

// IncrementFailedAttempts increments failed login attempts
func (u *UserModel) IncrementFailedAttempts() {
	u.FailedLoginAttempts++
	
	// Lock account after 5 failed attempts
	if u.FailedLoginAttempts >= 5 {
		u.Lock(30 * time.Minute) // Lock for 30 minutes
	}
}

// ResetFailedAttempts resets failed login attempts on successful login
func (u *UserModel) ResetFailedAttempts() {
	u.FailedLoginAttempts = 0
	u.LockedUntil = time.Time{}
	u.LastLogin = time.Now()
}

// SetPasswordChanged updates password change timestamp
func (u *UserModel) SetPasswordChanged() {
	u.PasswordChangedAt = time.Now()
}

// NeedsPasswordChange checks if password needs to be changed (90 days)
func (u *UserModel) NeedsPasswordChange() bool {
	if u.PasswordChangedAt.IsZero() {
		return true // Force password change if never set
	}
	return time.Since(u.PasswordChangedAt) > 90*24*time.Hour
}
